﻿namespace zijian666.WorkScheduler.Defaults;

/// <summary>
/// 表示一个可释放的对象。
/// </summary>
public abstract class DisposableBase : IDisposable
{
    protected DisposableBase()
    {
        _cts = new();
        _cts.Token.Register(Dispose);
    }
    protected readonly CancellationTokenSource _cts;

    private long disposedValue;

    /// <summary>
    /// 取消标记
    /// </summary>
    public CancellationToken Cancellation => _cts.IsCancellationRequested ? new CancellationToken(true) : _cts.Token;

    /// <summary>
    /// 是否已释放
    /// </summary>
    public bool IsDisposed => Interlocked.Read(ref disposedValue) == 1 || _cts.IsCancellationRequested;

    protected virtual void Dispose(bool disposing) { }

    /// <summary>
    /// 如果已经释放,则抛出异常
    /// </summary>
    protected void ThrowIfDisposed() => this.ThrowIfDisposed(IsDisposed);

    /// <inheritdoc />
    public void Dispose()
    {
        if (Interlocked.CompareExchange(ref disposedValue, 1, 0) == 0)
        {
            Dispose(disposing: true);
            if (!_cts.IsCancellationRequested)
            {
                _cts.Cancel();
            }
            _cts.TryDispose();
            GC.SuppressFinalize(this);
        }
    }
}
